#include <core_system/qls_core_system.h>
#include "./ui_qls_core_system.h"

#include <QDir>
#include <QPluginLoader>
#include <QMenu>
#include <QAction>
#include <QFile>
#include <QTextStream>
#include <QSettings>
#include <QTextCodec>
#include <QScreen>
#include <QPainter>
#include <qmath.h>

#include <QTableWidget>
#include <QTableWidgetItem>
#include <QHeaderView>
#include <QToolTip>
#include <QHBoxLayout>

#if 0
#include "../DevBase/dllQLsLog/dllqlslog.h"
#include "../DevBase/dllQLsLanguagesManager/qlslanguagesmanager.h"
#include "../../inc/QLsFunc/qlsfunc.h"
#elif 1
#include <log/qls_log.h>
#include <themes_manager/qls_themes_manager.h>
#include <languages_manager/qls_languages_manager.h>
#include <plugins_manager/qls_plugins_manager_pool.h>
#include <plugins_manager/qls_interface.h>
#include <settings/qls_settings.h>
#endif
static const QString g_pluginsDir = "plugins/QCoreSystem";

static const int SHADOW_WIDTH = 10; /* 阴影边框宽度 */

QLsCoreSystem::QLsCoreSystem(QWidget *parent)
    : QWidget(parent), ui(new Ui::QLsCoreSystem)
#if IsBorderLess
      ,
      m_bSize(true), m_bMove(true), m_bSizeOrMove(true), m_bPress(false)
#endif
{
    ui->setupUi(this);

    /* 日志初始化 */
    QLsLog::GetInstance().SetLogWindow(this);

    /* 主界面初始化 */
    HomeInit();

    /* 设置初始化 */
    SetInit();
}

QLsCoreSystem::~QLsCoreSystem()
{
    delete ui;
}
#if IsBorderLess
/* 鼠标事件重载 - 移动事件 */
void QLsCoreSystem::mouseMoveEvent(QMouseEvent *event)
{
    if (m_bPress) {
        if (isMaximized())
            return;
        /* 缩放 */
        if (m_bSizeOrMove) {
            if (m_bSize) {
                QPoint pt = event->pos();
                resize(pt.x(), pt.y());
            }
        }
        /* 移动 */
        else {
            if (m_bMove)
                move(event->globalPos() - m_PointWindow);
        }
    }

    QWidget::mouseMoveEvent(event);
}

/* 鼠标事件重载 - 按下事件 */
void QLsCoreSystem::mousePressEvent(QMouseEvent *event)
{
    if (event->buttons() == Qt::LeftButton) { /* 缩放：在右下20px处 */
        if (width() - 20 < event->pos().x() && event->pos().x() < width() &&
            height() - 20 < event->pos().y() && event->pos().y() < height()) {
            m_bSizeOrMove = true;
        }
        /* 移动 */
        else {
            m_bSizeOrMove = false;
            m_PointWindow = event->globalPos() - pos();
        }
        m_bPress = true;
        QWidget::mousePressEvent(event);
    }
}

/* 鼠标事件重载 - 释放事件 */
void QLsCoreSystem::mouseReleaseEvent(QMouseEvent *event)
{
    m_bPress = false;
    QWidget::mouseReleaseEvent(event);
}
#endif
/* 事件过滤器 */
bool QLsCoreSystem::eventFilter(QObject *target, QEvent *event)
{
    /* 标题栏双击 最大化/还原窗口 */
    if (target == ui->topWidget) {
        if (event->type() == QEvent::MouseButtonDblClick) {
            on_maxiBtn_clicked();
            return true;
        }
    }

    return QWidget::eventFilter(target, event);
}

/* 绘图事件重载 */
void QLsCoreSystem::paintEvent(QPaintEvent *event)
{
#if IsShadow
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.fillRect(
        QRect(SHADOW_WIDTH, SHADOW_WIDTH, width() - 2 * SHADOW_WIDTH,
              height() - 2 * SHADOW_WIDTH),
        QBrush(Qt::white));

    QColor color(0, 0, 0, 30);
    for (int i = 0; i < SHADOW_WIDTH; i++) {
        color.setAlpha(
            qvariant_cast<int>(200 - (double)i / SHADOW_WIDTH * 200));
        painter.setPen(color);
        // 圆角阴影边框;
        painter.drawRoundedRect(SHADOW_WIDTH - i, SHADOW_WIDTH - i,
                                width() - (SHADOW_WIDTH - i) * 2,
                                height() - (SHADOW_WIDTH - i) * 2, 4, 4);
    }
#endif

    QWidget::paintEvent(event);
}

/* 主界面初始化 */
void QLsCoreSystem::HomeInit()
{
#if IsBorderLess
    /* 隐藏窗口，只显示控件 */
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint);
    setAttribute(Qt::WA_TranslucentBackground);
#endif
    /* 标题栏注册事件过滤器，处理双击事件 */
    ui->topWidget->installEventFilter(this);
    ui->showTabWidget->installEventFilter(this);

    /* 日志显示表格初始化 */
    ui->recordTableWidget->horizontalHeader()->setDefaultAlignment(
        Qt::AlignHCenter | Qt::AlignVCenter);
    /* 样式 */
    ui->recordTableWidget->horizontalHeader()->setSectionResizeMode(
        0, QHeaderView::ResizeToContents); /* 自动适应内容 */
    ui->recordTableWidget->horizontalHeader()->setSectionResizeMode(
        1, QHeaderView::ResizeToContents); /* 自动适应内容 */
    ui->recordTableWidget->horizontalHeader()->setSectionResizeMode(
        2, QHeaderView::Stretch); /* 自动列宽并等宽 */

    /* 插件管理 */
    //	ui->showTabWidget->setTabStyle(QLsPluginsManagerAppfwk::QLsTabStyle::WEST);
    ui->showTabWidget->setPluginsDir(g_pluginsDir);
    connect(this, &QLsCoreSystem::sigLoad, ui->showTabWidget,
            &QLsPluginsManagerAppfwk::slotPluginLoad);

    /* 软件名 */
    QSettings settings(QString("%1/%2").arg(QLsSettings::getWorkSpace(),
                                            QLS_FILEPATH_SETTINGS),
                       QSettings::IniFormat);
    settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
    ui->titleLabel->setText(
        settings.value(QLS_KEY_SOFTWARE_NAME, tr("插件管理系统")).toString());
}

/* 设置初始化 */
void QLsCoreSystem::SetInit()
{
    /* ----- 设置的开头 ----- */
    /* 初始化本地主题 */
    QSettings settings(QLS_FILEPATH_SETTINGS, QSettings::IniFormat);
    settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
    m_curThemeName = settings.value(QLS_KEY_THEME, "white").toString();
    ui->showTabWidget->setCurThemeName(m_curThemeName);
    QLsThemesManager *themesManager = ui->showTabWidget->themesManager();
    themesManager->LoadTheme(this, m_curThemeName);

    /* 当前语言初始化 */
    QLsLanguagesManager &languagesManager = QLsLanguagesManager::GetInstance();
    m_curLangPack = languagesManager.GetCurrentLangPack();

    /* 添加设置按钮菜单 */
    QMenu *setMenu = new QMenu;
    ui->setBtn->setMenu(setMenu);

    /* ----- 设置的中间 ----- */
    /* 设置主题 */
    QMenu *setThemesMenu = setMenu->addMenu(tr("设置主题"));
    /* 获取当前可用主题 */
    for (QString theme : themesManager->GetThemes()) {
        /* 创建动作组 */
        QAction *action = new QAction(theme, this);

        /* 加入二级菜单 */
        setThemesMenu->addAction(action);

        action->setCheckable(true);
        if (theme == m_curThemeName)
            action->setChecked(true);
        else
            action->setChecked(false);
        connect(action, &QAction::triggered, this,
                &QLsCoreSystem::slotSetThemesActionsTriggered);
    }

    /* 加载全部插件 */
    ui->showTabWidget->LoadAllPlugin();

    /* 切换语言 */
    QMenu *changeLanguageMenu = setMenu->addMenu(tr("切换语言"));
    for (QString langPack : languagesManager.GetLangPacks()) {
        /* 创建动作组 */
        QAction *action =
            new QAction(QLsLanguagesManager::getLanguagesMap()[langPack], this);
        action->setData(langPack);

        /* 加入二级菜单 */
        changeLanguageMenu->addAction(action);

        action->setCheckable(true);
        if (langPack == m_curLangPack)
            action->setChecked(true);
        else
            action->setChecked(false);
        connect(action, &QAction::triggered, this,
                &QLsCoreSystem::slotChangeLanguageActionsTriggered);
    }
}
#if AUTO_ScaleUI
/* 缩放UI */
int QLsCoreSystem::ScaleUI(int spec)
{
    double rate = 0; /* 比例 */

    QList<QScreen *> screens = QApplication::screens();
    if (screens.size() > 0) {
        QScreen *screen = screens[0];
        double dpi = screen->logicalDotsPerInch();
        rate = dpi / 96.0;

        if (rate < 1.1)
            rate = 1.0;
        else if (rate < 1.4)
            rate = 1.25;
        else if (rate < 1.6)
            rate = 1.5;
        else if (rate < 1.8)
            rate = 1.75;
        else
            rate = 2.0;
    }

    m_preRate = rate;
    return (int)(spec * rate);
}

/* 根据缩放设置尺寸 */
void QLsCoreSystem::SetSizeWithScale(const QObject &obj)
{
    for (int i = 0; i < obj.children().size(); i++) {
        QWidget *pWidget = qobject_cast<QWidget *>(obj.children().at(i));
        if (pWidget != nullptr) {
            QSize preSize = pWidget->size();
            pWidget->setMinimumSize(pWidget->minimumSize() *
                                    m_scaleFromPreRate);
            pWidget->setMaximumSize(
                qMin((int)(pWidget->maximumWidth() * m_scaleFromPreRate),
                     16777215),
                qMin((int)(pWidget->maximumHeight() * m_scaleFromPreRate),
                     16777215));
            pWidget->resize(preSize * m_scaleFromPreRate);
            SetSizeWithScale(*(obj.children().at(i)));
        }
    }
}
#endif
/* 最大化/还原窗口 */
void QLsCoreSystem::on_maxiBtn_clicked()
{
    /* 还原 */
    if (isMaximized()) {
#if IsBorderLess
        /* 显示阴影边框 */
        ui->coreSystemGLayout->setMargin(5);
#endif

        /* 还原 */
        showNormal();
    }
    /* 最大化 */
    else {
#if IsBorderLess
        /* 隐藏阴影边框 */
        ui->coreSystemGLayout->setMargin(0);
#endif

        /* 最大化 */
        showFullScreen();
    }
}

/* 设置主题二级菜单的槽函数 */
void QLsCoreSystem::slotSetThemesActionsTriggered()
{
    /* 获取主题名 */
    QAction *action = qobject_cast<QAction *>(sender());
    QString themeName = action->text();
    if (m_curThemeName == themeName) {
        action->setChecked(true);
        return;
    }

    /* 加载主题 */
    if (!ui->showTabWidget->themesManager()->LoadTheme(this, themeName)) {
        action->setChecked(true);
        return;
    }

    /* 更新样式 */
    /* 原来的样式取消选中 */
    for (auto iAction :
         ((QMenu *)ui->setBtn->menu()->children()[1])->actions()) {
        if (iAction->text() == m_curThemeName) {
            iAction->setChecked(false);
            break;
        }
    }

    /* 更新为当前样式 */
    m_curThemeName = themeName;
    action->setChecked(true);
    QLOG_INFO() << "加载主题" << m_curThemeName.toUtf8().data();
}

/* 插件管理二级菜单的槽函数 */
void QLsCoreSystem::slotPluginManagerActionsTriggered()
{
    /* 获取插件名 */
    QAction *action = qobject_cast<QAction *>(sender());
    QString interfaceName = action->text();

    /* 获取插件信息 */
    QLsPluginsManager *pluginsManager =
        QLsPluginsManagerPool::GetInstance().GetPluginsManagerByPluginsDir(
            "plugins");
    PluginInfo info =
        pluginsManager->GetPluginInfoByInterfaceName(interfaceName);

    emit sigLoad(info);
}

/* 日志输出到控件 */
void QLsCoreSystem::slotWriteLog(const QString &message, int)
{
    /* 解析日志字符串"类型 时间 内容" */
    int levelLen = 5; /* 前5个字节是类型 */
    int timeLen = 23; /* 中间23个字节是时间 */
    int textLen = message.size() - (levelLen + 1) -
                  (timeLen + 1); /* 9之后的剩下的是内容 */

    QString levelStr = message.left(levelLen);
    QString timeStr = message.mid(levelLen + 1, timeLen);
    QString textStr = message.right(textLen);

    QTableWidgetItem *levelItem = new QTableWidgetItem(levelStr);
    QTableWidgetItem *timeItem = new QTableWidgetItem(timeStr);
    QTableWidgetItem *textItem = new QTableWidgetItem(textStr);

    /* 显示到日志表格上 */
    int row = ui->recordTableWidget->rowCount();
    ui->recordTableWidget->insertRow(row);
    ui->recordTableWidget->setItem(row, 0, levelItem);
    ui->recordTableWidget->setItem(row, 1, timeItem);
    ui->recordTableWidget->setItem(row, 2, textItem);

    /* 鼠标悬停提示完整内容 */
    textItem->setToolTip(textStr);

    /* 当前行自动下移 */
    ui->recordTableWidget->setCurrentCell(row, 0);
}

/* 切换语言二级菜单的槽函数 */
void QLsCoreSystem::slotChangeLanguageActionsTriggered()
{
    /* 获取主题名 */
    QAction *action = qobject_cast<QAction *>(sender());
    QString langPack = action->data().toString();
    if (m_curLangPack == langPack) {
        action->setChecked(true);
        return;
    }

    /* 加载语言 */
    if (!QLsLanguagesManager::GetInstance().LoadLangPack(langPack)) {
        action->setChecked(false);
        return;
    }

    /* 更新样式 */
    /* 原来的样式取消选中 */
    for (auto iAction :
         ((QMenu *)ui->setBtn->menu()->children()[2])->actions()) {
        if (iAction->data().toString() == m_curLangPack) {
            iAction->setChecked(false);
            break;
        }
    }

    /* 更新为当前样式 */
    m_curLangPack = langPack;
    action->setChecked(true);
    QLOG_INFO() << "加载语言包"
                << QLsLanguagesManager::getLanguagesMap()[m_curLangPack]
                << "成功，重启后才能生效！";
}

/* 登录的槽函数 */
void QLsCoreSystem::slotLogin(const User &user)
{
    me = user;

    show();

    /* 移动到鼠标所在显示器，并设置居中显示 */
#if 0
    QLsFunc::MoveWidgetToScreenWhereMouse(this);
#endif

    /* 获取显示器列表 */
    QList<QScreen *> screenList = QGuiApplication::screens();
    for (QScreen *screen : screenList) { /* 找到鼠标所在显示器 */
        if (screen->geometry().contains(QCursor::pos())) {
#if AUTO_ScaleUI
            /* 缩放比例 */
            connect(screen, &QScreen::logicalDotsPerInchChanged, this,
                    &QLsCoreSystem::onLogicalDotsPerInchChanged);
#endif
            break;
        }
    }

    /* 初始最大化界面（结合上一步，会在鼠标所在显示器最大化显示） */
    //	on_maxiBtn_clicked();
}

#if AUTO_ScaleUI
/* windows缩放(每英寸逻辑点)的变化 的槽函数 */
void QLsCoreSystem::onLogicalDotsPerInchChanged(qreal dpi)
{
    m_scaleFromPreRate = (double)dpi / 96 / m_preRate;
    m_preRate = (double)dpi / 96;
    SetSizeWithScale(*this);
}
#endif
/* 日志表格右键菜单 */
void QLsCoreSystem::on_recordTableWidget_customContextMenuRequested(
    const QPoint &pos)
{
    QTableWidgetItem *selecteditem = ui->recordTableWidget->itemAt(pos);
    if (!selecteditem)
        return;

    /* 清空 */
    QAction *clearAction = new QAction(tr("清空"), this);
    clearAction->setObjectName("clearAction");
    connect(clearAction, &QAction::triggered, this,
            &QLsCoreSystem::slotRecordActionDeal);

    /* 删除 */
    QAction *deleteAction = new QAction(tr("删除"), this);
    deleteAction->setObjectName("deleteAction");
    deleteAction->setData(selecteditem->row());
    connect(deleteAction, &QAction::triggered, this,
            &QLsCoreSystem::slotRecordActionDeal);

    /* 弹出菜单 */
    QMenu *menu = new QMenu(this);
    menu->setObjectName("recordTableWidgetMenu");
    menu->addAction(clearAction);
    menu->addAction(deleteAction);
    menu->popup(ui->recordTableWidget->viewport()->mapToGlobal(pos));
}

/* 日志表格右键菜单消息处理的槽函数 */
void QLsCoreSystem::slotRecordActionDeal()
{
    QAction *action = qobject_cast<QAction *>(sender());
    if (!action)
        return;

    QMutexLocker locker(&m_recordTableWidgetMutex);

    /* 清空 */
    if (action->text() == tr("清空")) { /* 只删内容，不清空设置 */
        while (ui->recordTableWidget->rowCount())
            ui->recordTableWidget->removeRow(0);
    }
    /* 删除 */
    else if (action->text() == tr("删除")) {
        ui->recordTableWidget->removeRow(action->data().toInt());
    }
}

/* 加载、卸载插件的槽函数 */
void QLsCoreSystem::slotPluginLoad(PluginInfo &pluginInfo)
{
    /* 根据name找到action */
    QAction *action = nullptr;
    for (QAction *iAction :
         ((QMenu *)ui->setBtn->menu()->children()[2])->actions()) {
        if (iAction->text() == pluginInfo.m_interfaceInfo->m_name) {
            action = iAction;
            break;
        }
    }

    if (!action)
        return;

    /* 卸载插件 */
    if (pluginInfo.m_isLoaded) {
        /* 菜单栏改为卸载状态 */
        action->setChecked(false);
    }
    /* 加载插件 */
    else {
        /* 菜单栏改为加载状态 */
        action->setChecked(true);
    }
}
